package com.js.foodordersystem.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.js.foodordersystem.config.AlipayConfig;
import com.js.foodordersystem.dto.OrderDTO;
import com.js.foodordersystem.dto.OrderItemDTO;
import com.js.foodordersystem.entity.*;
import com.js.foodordersystem.service.*;
import com.js.foodordersystem.util.JwtUtil;
import com.js.foodordersystem.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Controller
@RequestMapping("/alipay")
@Transactional(rollbackFor = Exception.class)
public class AliPayController {

    @Resource
    private OrderService orderService;
    @Resource
    private DishService dishService;
    @Resource
    private PaymentService paymentService;
    @Resource
    private OrderItemService orderItemService;
    @Resource
    private CartService cartService;

    @PostMapping("/pay")
    public void pay(HttpServletResponse httpResponse, @RequestBody Order order, HttpServletRequest request) throws Exception {
        // 判断是否为空
        if (order == null) {
            httpResponse.setStatus(HttpStatus.BAD_REQUEST.value());
            httpResponse.getWriter().write("参数错误");
            return;
        }

        // 获取菜品信息
        Dish dish = dishService.getById(order.getDishId());
        if (dish == null) {
            httpResponse.setStatus(HttpStatus.BAD_REQUEST.value());
            httpResponse.getWriter().write("菜品不存在");
            return;
        }

        // 生成订单
        Long id = JwtUtil.getUserIdFromToken(request.getHeader("token"));
        order.setUserId(id);
        order.setTotalPrice(dish.getPrice().multiply(new BigDecimal(order.getQuantity())));
        orderService.save(order);

        // 生成订单详情
        OrderItem orderItem = new OrderItem();
        orderItem.setOrderId(order.getOrderId());
        orderItem.setDishId(order.getDishId());
        orderItem.setQuantity(order.getQuantity());
        orderItem.setPrice(dish.getPrice());
        orderItem.setTotalPrice(order.getTotalPrice());
        orderItemService.save(orderItem);

        // 生成付款信息
        Payment payment = new Payment();
        payment.setOrderId(order.getOrderId());
        payment.setPaymentMethod(order.getPaymentMethod());
        payment.setPaymentStatus(10); // 10 表示待支付
        payment.setPaymentTime(null);
        paymentService.save(payment);

        // 调用支付宝接口生成支付表单
        AlipayClient alipayClient = new DefaultAlipayClient(
                AlipayConfig.URL,
                AlipayConfig.APPID,
                AlipayConfig.RSA_PRIVATE_KEY,
                AlipayConfig.FORMAT,
                AlipayConfig.CHARSET,
                AlipayConfig.ALIPAY_PUBLIC_KEY,
                AlipayConfig.SIGNTYPE
        );

        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setNotifyUrl(AlipayConfig.NOTIFY_URL); // 异步通知地址
        alipayRequest.setReturnUrl(AlipayConfig.RETURN_URL); // 同步通知地址

        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setOutTradeNo(order.getOrderId().toString()); // 商户订单号
        model.setTotalAmount(order.getTotalPrice().toString()); // 订单金额
        model.setSubject("网上订餐系统"); // 订单标题
        model.setProductCode("FAST_INSTANT_TRADE_PAY"); // 产品码
        alipayRequest.setBizModel(model);

        // 获取支付表单
        String formHtml = alipayClient.pageExecute(alipayRequest).getBody();
        log.info("支付宝支付表单: {}", formHtml);

        // 返回支付表单
        httpResponse.setContentType("text/html;charset=utf-8");
        httpResponse.getWriter().write(formHtml);
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    @PostMapping("/pay-multi")
    public void payMulti(HttpServletResponse httpResponse, @RequestBody OrderDTO orderDTO, HttpServletRequest request) throws Exception {
        // 判断是否为空
        if (orderDTO == null || orderDTO.getItems() == null || orderDTO.getItems().isEmpty()) {
            httpResponse.setStatus(HttpStatus.BAD_REQUEST.value());
            httpResponse.getWriter().write("参数错误");
            return;
        }

        // 获取用户ID
        Long userId = JwtUtil.getUserIdFromToken(request.getHeader("token"));
        orderDTO.setUserId(userId);

        // 计算订单总金额
        BigDecimal totalPrice = orderDTO.getItems().stream()
                .map(item -> item.getPrice().multiply(new BigDecimal(item.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        orderDTO.setTotalPrice(totalPrice);

        // 生成订单
        Order order = new Order();
        order.setUserId(orderDTO.getUserId());
        order.setAddressId(orderDTO.getAddressId());
        order.setTotalPrice(orderDTO.getTotalPrice());
        order.setPaymentMethod(orderDTO.getPaymentMethod());
        order.setOrderStatus(orderDTO.getOrderStatus());
        orderService.save(order);

        // 生成订单项
        for (OrderItemDTO item : orderDTO.getItems()) {
            OrderItem orderItem = new OrderItem();
            orderItem.setOrderId(order.getOrderId());
            orderItem.setDishId(item.getDishId());
            orderItem.setQuantity(item.getQuantity());
            orderItem.setPrice(item.getPrice());
            orderItem.setTotalPrice(item.getPrice().multiply(new BigDecimal(item.getQuantity())));
            orderItemService.save(orderItem);

            //删除购物车内容
            // 删除购物车内容
            Cart cart = new Cart();
            cart.setUserId(userId);
            cart.setDishId(item.getDishId());
            cartService.remove(new QueryWrapper<>(cart));
        }

        // 生成付款信息
        Payment payment = new Payment();
        payment.setOrderId(order.getOrderId());
        payment.setPaymentMethod(orderDTO.getPaymentMethod());
        payment.setPaymentStatus(10); // 10 表示待支付
        payment.setPaymentTime(null);
        paymentService.save(payment);

        // 调用支付宝接口生成支付表单
        AlipayClient alipayClient = new DefaultAlipayClient(
                AlipayConfig.URL,
                AlipayConfig.APPID,
                AlipayConfig.RSA_PRIVATE_KEY,
                AlipayConfig.FORMAT,
                AlipayConfig.CHARSET,
                AlipayConfig.ALIPAY_PUBLIC_KEY,
                AlipayConfig.SIGNTYPE
        );

        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setNotifyUrl(AlipayConfig.NOTIFY_URL); // 异步通知地址
        alipayRequest.setReturnUrl(AlipayConfig.RETURN_URL); // 同步通知地址

        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setOutTradeNo(order.getOrderId().toString()); // 商户订单号
        model.setTotalAmount(order.getTotalPrice().toString()); // 订单金额
        model.setSubject("网上订餐系统 - 多菜品订单"); // 订单标题
        model.setProductCode("FAST_INSTANT_TRADE_PAY"); // 产品码
        alipayRequest.setBizModel(model);

        // 获取支付表单
        String formHtml = alipayClient.pageExecute(alipayRequest).getBody();
        log.info("支付宝支付表单: {}", formHtml);

        // 返回支付表单
        httpResponse.setContentType("text/html;charset=utf-8");
        httpResponse.getWriter().write(formHtml);
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    @PostMapping("/notifyUrl")
    public String notifyUrl(HttpServletRequest request) throws AlipayApiException {
        Map<String, String[]> requestParams = request.getParameterMap();
        Map<String, String> params = new HashMap<>();
        for (String key : requestParams.keySet()) {
            String[] values = requestParams.get(key);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            params.put(key, valueStr);
        }

        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);
        if (signVerified) {
            // 验证支付状态
            String tradeStatus = params.get("trade_status");
            log.info("notifyUrl：支付状态：{}", tradeStatus);
            if ("TRADE_SUCCESS".equals(tradeStatus)) {
                String outTradeNo = params.get("out_trade_no");
                UpdateWrapper<Payment> paymentUpdateWrapper = new UpdateWrapper<>();
                paymentUpdateWrapper.eq("order_id", outTradeNo);
                paymentUpdateWrapper.set("payment_status", 2)
                        .set("payment_time", new Date());
                paymentService.update(paymentUpdateWrapper);
                return "success";
            }
        }
        log.info("notifyUrl：支付校验失败");
        return "failure";
    }


    @GetMapping("/returnUrl")
    public void returnUrl(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
        Map<String, String[]> requestParams = request.getParameterMap();
        Map<String, String> params = new HashMap<>();
        for (String key : requestParams.keySet()) {
            String[] values = requestParams.get(key);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            params.put(key, valueStr);
        }

        // 打印各个参数
        for (String key : params.keySet()) {
            log.info("returnUrl：{} = {}", key, params.get(key));
        }

        // 验证签名
        boolean signVerified = false;
        try {
            signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);
        } catch (AlipayApiException e) {
            log.error("签名验证失败", e);
        }

        String outTradeNo = params.get("out_trade_no");
        if (signVerified) {
            // 调用支付宝订单查询接口，获取支付状态
            AlipayClient alipayClient = new DefaultAlipayClient(
                    AlipayConfig.URL,
                    AlipayConfig.APPID,
                    AlipayConfig.RSA_PRIVATE_KEY,
                    AlipayConfig.FORMAT,
                    AlipayConfig.CHARSET,
                    AlipayConfig.ALIPAY_PUBLIC_KEY,
                    AlipayConfig.SIGNTYPE
            );

            AlipayTradeQueryRequest queryRequest = new AlipayTradeQueryRequest();
            queryRequest.setBizContent("{" +
                    "\"out_trade_no\":\"" + outTradeNo + "\"" +
                    "}");

            // 执行查询
            AlipayTradeQueryResponse queryResponse = alipayClient.execute(queryRequest);
            log.info("returnUrl：查询结果：{}", queryResponse.getBody());
            if (queryResponse.isSuccess()) {
                String tradeStatus = queryResponse.getTradeStatus();
                if ("TRADE_SUCCESS".equals(tradeStatus)) {
                    // 支付成功，跳转到前端成功页面
                    response.sendRedirect("http://192.168.149.234:5173/#/pay/paySuccess");
                } else {
                    // 支付失败，更新订单状态
                    UpdateWrapper<Payment> paymentUpdateWrapper = new UpdateWrapper<>();
                    paymentUpdateWrapper.eq("order_id", outTradeNo);
                    paymentUpdateWrapper.set("payment_status", 3)
                            .set("payment_time", new Date());
                    paymentService.update(paymentUpdateWrapper);
                    log.error("支付失败，交易状态: {}", tradeStatus);
                    // 跳转到前端失败页面
                    response.sendRedirect("http://192.168.149.234:5173/#/pay/payFail");
                }
            } else {
                log.error("支付宝订单查询失败: {}", queryResponse.getSubMsg());
                response.sendRedirect("http://192.168.149.234:5173/#/pay/payFail");
            }
        } else {
            // 签名验证失败，更新订单状态
            UpdateWrapper<Payment> paymentUpdateWrapper = new UpdateWrapper<>();
            paymentUpdateWrapper.eq("order_id", outTradeNo);
            paymentUpdateWrapper.set("payment_status", 9)
                    .set("payment_time", new Date());
            paymentService.update(paymentUpdateWrapper);
            log.error("签名验证失败");
            // 跳转到前端失败页面
            response.sendRedirect("http://192.168.149.234:5173/#/pay/payFail");
        }
    }

}
